package glogwrap

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/golang/glog"
	"time"
)

var tags = []string{"INFO", "WARNING", "ERROR"}

var ostype = os.Getenv("GOOS") //

var infoList, warnList, errorList, delList []os.FileInfo

// shortHostname returns its argument, truncating at the first period.
// For instance, given "www.google.com" it returns "www".
func shortHostname(hostname string) string {
	if i := strings.Index(hostname, "."); i >= 0 {
		return hostname[:i]
	}
	return hostname
}

func getLogName() string {
	program := filepath.Base(os.Args[0])
	host := "unknownhost"
	userName := "unknownuser"

	h, err := os.Hostname()
	if err == nil {
		host = shortHostname(h)
	}

	current, err := user.Current()
	if err == nil {
		userName = current.Username
	}

	// Sanitize userName since it may contain filepath separators on Windows.
	userName = strings.Replace(userName, `\`, "_", -1)
	return fmt.Sprintf("%s.%s.%s.log", program, host, userName)
}

func rmLogs(logList []os.FileInfo, logDir string) {
	for _, fi := range logList {
		fPath := logDir + "/" + fi.Name()
		if ostype == "windows" {
			fPath = logDir + "\\" + fi.Name()
		}
		err := os.Remove(fPath)
		if err == nil {
			println("removed ", fPath)
		}
	}
}

func logClean(num int, logDir string) {
	logBaseName := getLogName()

	for true {
		infoList = make([]os.FileInfo, 0, num)
		warnList = make([]os.FileInfo, 0, num)
		errorList = make([]os.FileInfo, 0, num)
		delList = make([]os.FileInfo, 0, num*2)

		getFiles(logDir, logBaseName, num)

		rmLogs(delList, logDir)

		time.Sleep(time.Second * 2)
	}
}

//LogInit(1024*1024*100, 5, false, "WARNING", 2, "./logs")
func LogInit(fileSize uint64, fileNum int, alsoStderr bool, stderrThreshold string, v int, logDir string) {
	glog.MaxSize = fileSize
	if alsoStderr {
		flag.Set("alsologtostderr", "true")
	}
	flag.Set("stderrthreshold", stderrThreshold)
	flag.Set("v", strconv.Itoa(v))
	flag.Set("log_dir", logDir)

	flag.Parse()

	go logClean(fileNum, logDir)
}

func insertList(fList []os.FileInfo, f os.FileInfo, fNum int) []os.FileInfo {
	if len(fList) < fNum {
		fList = append(fList, f)
	} else {
		iTmp := 0
		for i, fi := range fList {
			if fi.ModTime().Before(fList[iTmp].ModTime()) {
				iTmp = i
			}
		}

		if f.ModTime().Before(fList[iTmp].ModTime()) {
			delList = append(delList, f)
		} else {
			delList = append(delList, fList[iTmp])
			fList[iTmp] = f
		}
	}

	return fList
}

func getFiles(path, logName string, fNum int) {
	files, _ := ioutil.ReadDir(path)
	for _, fi := range files {
		if !fi.IsDir() {
			if ok := strings.HasPrefix(fi.Name(), logName+".INFO"); ok {
				infoList = insertList(infoList, fi, fNum)
			} else if ok := strings.HasPrefix(fi.Name(), logName+".WARNING"); ok {
				warnList = insertList(warnList, fi, fNum)
			} else if ok := strings.HasPrefix(fi.Name(), logName+".ERROR"); ok {
				errorList = insertList(errorList, fi, fNum)
			}
		}
	}
}
